home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 1 / BBS in a box - Trilogy I.iso / Files / Publish / Photoshop / Plug-in Modules / Code / SimpleFormat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-28  |  15.2 KB  |  855 lines  |  [TEXT/MPS ]

  1. /*
  2.     File: SimpleFormat.c
  3.  
  4.     Copyright 1993 by Adobe Systems, Inc.
  5.  
  6. */
  7.  
  8. #include <Types.h>
  9. #include <Memory.h>
  10. #include <Resources.h>
  11. #include <QuickDraw.h>
  12. #include <Dialogs.h>
  13. #include <OSUtils.h>
  14. #include <Packages.h>
  15. #include <Errors.h>
  16. #include <ToolUtils.h>
  17.  
  18. #include "PITypes.h"
  19. #include "PIGeneral.h"
  20. #include "PIFormat.h"
  21.  
  22. #include "DialogUtilities.h"
  23. #include "PIUtilities.h"
  24.  
  25. #ifdef THINK_C
  26.  
  27. #define ENTRYPOINT main
  28.  
  29. #endif
  30.  
  31. /*****************************************************************************/
  32.  
  33. typedef struct GlobalData
  34.     {
  35.  
  36.     FormatRecordPtr    stuff;
  37.     short            result;
  38.     
  39.     BufferID        pixelBuffer;
  40.     Ptr                pixelData;
  41.     
  42.     int32            rowBytes;
  43.     
  44.     int32            done;
  45.     int32            total;
  46.         
  47.     } Globals, *GPtr, **GHdl;
  48.     
  49. /*****************************************************************************/
  50.  
  51. #define gStuff       ((**globals).stuff)
  52. #define gResult      ((**globals).result)
  53.  
  54. #define gPixelBuffer ((**globals).pixelBuffer)
  55. #define gPixelData   ((**globals).pixelData)
  56.  
  57. #define gRowBytes    ((**globals).rowBytes)
  58.  
  59. #define gDone        ((**globals).done)
  60. #define gTotal       ((**globals).total)
  61.  
  62. /*****************************************************************************/
  63.  
  64. void InitGlobals (GHdl globals);
  65.  
  66. void DoAbout (GHdl globals);
  67. void DoReadPrepare (GHdl globals);
  68. void DoReadStart (GHdl globals);
  69. void DoReadContinue (GHdl globals);
  70. void DoReadFinish (GHdl globals);
  71. void DoOptionsPrepare (GHdl globals);
  72. void DoOptionsStart (GHdl globals);
  73. void DoOptionsContinue (GHdl globals);
  74. void DoOptionsFinish (GHdl globals);
  75. void DoEstimatePrepare (GHdl globals);
  76. void DoEstimateStart (GHdl globals);
  77. void DoEstimateContinue (GHdl globals);
  78. void DoEstimateFinish (GHdl globals);
  79. void DoWritePrepare (GHdl globals);
  80. void DoWriteStart (GHdl globals);
  81. void DoWriteContinue (GHdl globals);
  82. void DoWriteFinish (GHdl globals);
  83.  
  84. /*****************************************************************************/
  85.  
  86. typedef struct FileHeader
  87.     {
  88.     
  89.     int16 mode;
  90.     int16 depth;
  91.     int16 rows;
  92.     int16 cols;
  93.     int16 planes;
  94.     
  95.     int32 resourceLength;
  96.     
  97.     } FileHeader;
  98.  
  99. /*****************************************************************************/
  100.  
  101. /* Main dispatching routine.  Initializes and sets up the global variables,
  102.    and performs the operation specified by the selector. */
  103.  
  104. pascal void ENTRYPOINT (short selector,
  105.                         FormatRecordPtr stuff,
  106.                         long *data,
  107.                         short *result)
  108.     {
  109.  
  110.     /* Set up the globals. */
  111.  
  112.     GHdl globals;
  113.     
  114.     if (!*data)
  115.         {
  116.  
  117.         *data = (long) NewHandle (sizeof (Globals));
  118.         
  119.         if (!*data)
  120.             {
  121.             *result = memFullErr;
  122.             return;
  123.             }
  124.             
  125.         InitGlobals ((GHdl) *data);
  126.         
  127.         }
  128.         
  129.     globals = (GHdl) *data;
  130.     
  131.     /* Perform the requested operation */
  132.  
  133.     gStuff  = stuff;
  134.     gResult = noErr;
  135.  
  136.     switch (selector)
  137.         {
  138.  
  139.         case formatSelectorAbout:
  140.             DoAbout (globals);
  141.             break;
  142.  
  143.         case formatSelectorReadPrepare:
  144.             DoReadPrepare (globals);
  145.             break;
  146.  
  147.         case formatSelectorReadStart:
  148.             DoReadStart (globals);
  149.             break;
  150.  
  151.         case formatSelectorReadContinue:
  152.             DoReadContinue (globals);
  153.             break;
  154.  
  155.         case formatSelectorReadFinish:
  156.             DoReadFinish (globals);
  157.             break;
  158.  
  159.         case formatSelectorOptionsPrepare:
  160.             DoOptionsPrepare (globals);
  161.             break;
  162.  
  163.         case formatSelectorOptionsStart:
  164.             DoOptionsStart (globals);
  165.             break;
  166.  
  167.         case formatSelectorOptionsContinue:
  168.             DoOptionsContinue (globals);
  169.             break;
  170.  
  171.         case formatSelectorOptionsFinish:
  172.             DoOptionsFinish (globals);
  173.             break;
  174.  
  175.         case formatSelectorEstimatePrepare:
  176.             DoEstimatePrepare (globals);
  177.             break;
  178.  
  179.         case formatSelectorEstimateStart:
  180.             DoEstimateStart (globals);
  181.             break;
  182.  
  183.         case formatSelectorEstimateContinue:
  184.             DoEstimateContinue (globals);
  185.             break;
  186.  
  187.         case formatSelectorEstimateFinish:
  188.             DoEstimateFinish (globals);
  189.             break;
  190.  
  191.         case formatSelectorWritePrepare:
  192.             DoWritePrepare (globals);
  193.             break;
  194.  
  195.         case formatSelectorWriteStart:
  196.             DoWriteStart (globals);
  197.             break;
  198.  
  199.         case formatSelectorWriteContinue:
  200.             DoWriteContinue (globals);
  201.             break;
  202.  
  203.         case formatSelectorWriteFinish:
  204.             DoWriteFinish (globals);
  205.             break;
  206.  
  207.         default:
  208.             gResult = formatBadParameters;
  209.         }
  210.  
  211.     *result = gResult;
  212.  
  213.     }
  214.  
  215. /*****************************************************************************/
  216.  
  217. /* Sets the global variables to their default values. */
  218.  
  219. void InitGlobals (GHdl globals)
  220.     {
  221.  
  222.     Ptr        p;
  223.     int16    count;
  224.     
  225.     p = (Ptr) *globals;
  226.     count = sizeof(Globals);
  227.     
  228.     while (count--)
  229.         *p++ = 0;
  230.  
  231.     }
  232.  
  233. /*****************************************************************************/
  234.  
  235. /* Displays the about dialog box for the plug-in module. */
  236.  
  237. void DoAbout (GHdl globals)
  238.     {
  239.  
  240.     #pragma unused (globals)
  241.     
  242.     #define dialogID 16000
  243.     
  244.     ShowAbout (dialogID);
  245.  
  246.     #undef dialogID
  247.  
  248.     }
  249.  
  250. /*****************************************************************************/
  251.  
  252. Boolean CheckForServices (GHdl globals)
  253.     {
  254.     
  255.     return WarnBufferProcsAvailable ();
  256.     
  257.     }
  258.  
  259. /*****************************************************************************/
  260.  
  261. int32 RowBytes (GHdl globals)
  262.     {
  263.     
  264.     return (gStuff->imageSize.h * (int32) gStuff->depth + 7) >> 3;
  265.     
  266.     }
  267.  
  268. /*****************************************************************************/
  269.  
  270. void AllocatePixelBuffer (GHdl globals)
  271.     {
  272.     
  273.     BufferID buffer;
  274.  
  275.     /* We will want a buffer that is one line wide. */
  276.     
  277.     gPixelBuffer = 0;
  278.     
  279.     gRowBytes = RowBytes (globals);
  280.     
  281.     gResult = AllocateBuffer (gRowBytes, &buffer);
  282.     
  283.     if (gResult == noErr)
  284.         {
  285.         
  286.         gPixelBuffer = buffer;
  287.         
  288.         gPixelData = LockBuffer (gPixelBuffer, FALSE);
  289.         
  290.         }
  291.     
  292.     }
  293.  
  294. /*****************************************************************************/
  295.  
  296. void DisposePixelBuffer (GHdl globals)
  297.     {
  298.     
  299.     if (gPixelBuffer)
  300.         {
  301.         
  302.         BufferID buffer = gPixelBuffer; /* Globals can move! */
  303.         
  304.         FreeBuffer (buffer);
  305.         
  306.         gPixelBuffer = 0;
  307.         gPixelData = 0;
  308.         
  309.         }
  310.     
  311.     }
  312.  
  313. /*****************************************************************************/
  314.  
  315. void DoReadPrepare (GHdl globals)
  316.     {
  317.     
  318.     /* Allow some space for the image resources if handle procs
  319.        are unavailable. */
  320.     
  321.     if (!HandleProcsAvailable (NULL))
  322.         gStuff->maxData = 0x010000L;
  323.         
  324.     else
  325.         gStuff->maxData = 0;
  326.     
  327.     }
  328.  
  329. /*****************************************************************************/
  330.  
  331. void ReadSome (GHdl globals, int32 count, void *buffer)
  332.     {
  333.     
  334.     int32 readCount = count;
  335.     
  336.     if (gResult != noErr)
  337.         return;
  338.     
  339.     gResult = FSRead (gStuff->dataFork, &readCount, buffer);
  340.     
  341.     if (gResult == noErr && readCount != count)
  342.         gResult = eofErr;
  343.     
  344.     }
  345.  
  346. /*****************************************************************************/
  347.  
  348. void WriteSome (GHdl globals, int32 count, void *buffer)
  349.     {
  350.     
  351.     int32 writeCount = count;
  352.     
  353.     if (gResult != noErr)
  354.         return;
  355.     
  356.     gResult = FSWrite (gStuff->dataFork, &writeCount, buffer);
  357.     
  358.     if (gResult == noErr && writeCount != count)
  359.         gResult = dskFulErr;
  360.     
  361.     }
  362.  
  363. /*****************************************************************************/
  364.  
  365. void ReadRow (GHdl globals)
  366.     {
  367.     
  368.     ReadSome (globals, gRowBytes, gPixelData);
  369.     
  370.     }
  371.  
  372. /*****************************************************************************/
  373.  
  374. void WriteRow (GHdl globals)
  375.     {
  376.     
  377.     WriteSome (globals, gRowBytes, gPixelData);
  378.     
  379.     }
  380.  
  381. /*****************************************************************************/
  382.  
  383. void DisposeImageResources (GHdl globals)
  384.     {
  385.     
  386.     if (gStuff->imageRsrcData)
  387.         {
  388.         
  389.         PIDisposeHandle (gStuff->imageRsrcData);
  390.         
  391.         gStuff->imageRsrcData = NULL;
  392.         
  393.         gStuff->imageRsrcSize = 0;
  394.         
  395.         }
  396.     
  397.     }
  398.  
  399. /*****************************************************************************/
  400.  
  401. void DoReadStart (GHdl globals)
  402.     {
  403.     
  404.     FileHeader header;
  405.     
  406.     /* Exit if we have already encountered an error. */
  407.  
  408.     if (gResult != noErr)
  409.         return;
  410.         
  411.     /* Check for the needed services. */
  412.     
  413.     if (!CheckForServices (globals))
  414.         {
  415.         gResult = 1;
  416.         return;
  417.         }
  418.  
  419.     /* If we have not encountered an error, then we want to read
  420.        the file header. */
  421.     
  422.     gResult = SetFPos (gStuff->dataFork, fsFromStart, 0);
  423.     
  424.     ReadSome (globals, sizeof (FileHeader), &header);
  425.     
  426.     if (gResult != noErr)
  427.         return;
  428.     
  429.     gStuff->imageMode = header.mode;
  430.     gStuff->imageSize.v = header.rows;
  431.     gStuff->imageSize.h = header.cols;
  432.     gStuff->depth = header.depth;
  433.     gStuff->planes = header.planes;
  434.     
  435.     /* Next, we will try to read the image resources. */
  436.     
  437.     if (header.resourceLength > 0)
  438.         {
  439.         
  440.         gStuff->imageRsrcData = PINewHandle (header.resourceLength);
  441.         
  442.         if (!gStuff->imageRsrcData)
  443.             {
  444.             gResult = memFullErr;
  445.             return;
  446.             }
  447.             
  448.         ReadSome (globals,
  449.                   header.resourceLength,
  450.                   PILockHandle (gStuff->imageRsrcData, FALSE));
  451.         
  452.         PIUnlockHandle (gStuff->imageRsrcData);
  453.         
  454.         if (gResult != noErr)
  455.             goto CleanUp;
  456.             
  457.         gStuff->imageRsrcSize = header.resourceLength;
  458.         
  459.         }
  460.         
  461.     /* Next, we will will read the lookup tables if in indexed color mode. */
  462.     
  463.     if (header.mode == plugInModeIndexedColor)
  464.         {
  465.         
  466.         ReadSome (globals, 3 * sizeof (LookUpTable), &gStuff->redLUT);
  467.         
  468.         if (gResult != noErr)
  469.             goto CleanUp;
  470.         
  471.         }
  472.         
  473.     /* Set up the progress variables. */
  474.     
  475.     gDone = 0;
  476.     gTotal = header.rows * (long) header.planes;
  477.         
  478.     /* Next, we will allocate the pixel buffer. */
  479.     
  480.     AllocatePixelBuffer (globals);
  481.     
  482.     if (gResult != noErr)
  483.         goto CleanUp;
  484.         
  485.     /* Set up to start returning chunks of data. */
  486.     
  487.     gStuff->theRect.top = 0;
  488.     gStuff->theRect.bottom = 1;
  489.     gStuff->theRect.left = 0;
  490.     gStuff->theRect.right = header.cols;
  491.     gStuff->loPlane = 0;
  492.     gStuff->hiPlane = 0;
  493.     gStuff->colBytes = 1;
  494.     gStuff->rowBytes = gRowBytes;
  495.     gStuff->planeBytes = 0;
  496.     
  497.     /* Read that chunk of data. */
  498.     
  499.     ReadRow (globals);
  500.     
  501.     if (gResult == noErr)
  502.         {
  503.         gStuff->data = gPixelData;
  504.         return;
  505.         }
  506.     
  507.     /* The following code does any clean-up work in the event of an error. */
  508.     
  509.     CleanUp:
  510.     
  511.     DisposeImageResources (globals);
  512.     
  513.     DisposePixelBuffer (globals);
  514.         
  515.     }
  516.  
  517. /*****************************************************************************/
  518.  
  519. void DoReadContinue (GHdl globals)
  520.     {
  521.     
  522.     /* Dispose of the image resource data if it exists. */
  523.     
  524.     DisposeImageResources (globals);
  525.     
  526.     /* Exit if we have an error. */
  527.     
  528.     if (gResult != noErr)
  529.         {
  530.         gStuff->data = NULL;
  531.         return;
  532.         }
  533.  
  534.     /* Advance the rectangle. */
  535.     
  536.     gStuff->theRect.top++;
  537.     gStuff->theRect.bottom++;
  538.     
  539.     /* If we have gone off the end, advance the plane. */
  540.     
  541.     if (gStuff->theRect.top >= gStuff->imageSize.v)
  542.         {
  543.         
  544.         gStuff->theRect.top = 0;
  545.         gStuff->theRect.bottom = 1;
  546.         
  547.         gStuff->loPlane++;
  548.         gStuff->hiPlane++;
  549.         
  550.         /* If we are past the last plane.  Set data to NULL and return. */
  551.         
  552.         if (gStuff->loPlane >= gStuff->planes)
  553.             {
  554.             
  555.             gStuff->data = NULL;
  556.             
  557.             return;
  558.             
  559.             }
  560.         
  561.         }
  562.         
  563.     ReadRow (globals);
  564.     
  565.     ++gDone;
  566.     
  567.     UpdateProgress (gDone, gTotal);
  568.     
  569.     }
  570.  
  571. /*****************************************************************************/
  572.  
  573. void DoReadFinish (GHdl globals)
  574.     {
  575.     
  576.     /* Dispose of the image resource data if it exists. */
  577.     
  578.     DisposeImageResources (globals);
  579.     
  580.     /* Free the pixel buffer. */
  581.     
  582.     DisposePixelBuffer (globals);
  583.     
  584.     gStuff->data = NULL;
  585.     
  586.     }
  587.  
  588. /*****************************************************************************/
  589.  
  590. void DoOptionsPrepare (GHdl globals)
  591.     {
  592.  
  593.     gStuff->maxData = 0;
  594.  
  595.     }
  596.  
  597. /*****************************************************************************/
  598.  
  599. void DoOptionsStart (GHdl globals)
  600.     {
  601.  
  602.     /* Check for the needed services. */
  603.     
  604.     if (!CheckForServices (globals))
  605.         {
  606.         gResult = 1;
  607.         return;
  608.         }
  609.  
  610.     gStuff->data = NULL;
  611.  
  612.     }
  613.  
  614. /*****************************************************************************/
  615.  
  616. void DoOptionsContinue (GHdl globals)
  617.     {
  618.  
  619.     #pragma unused (globals)
  620.  
  621.     }
  622.  
  623. /*****************************************************************************/
  624.  
  625. void DoOptionsFinish (GHdl globals)
  626.     {
  627.  
  628.     #pragma unused (globals)
  629.  
  630.     }
  631.  
  632. /*****************************************************************************/
  633.  
  634. void DoEstimatePrepare (GHdl globals)
  635.     {
  636.  
  637.     gStuff->maxData = 0;
  638.  
  639.     }
  640.  
  641. /*****************************************************************************/
  642.  
  643. void DoEstimateStart (GHdl globals)
  644.     {
  645.     
  646.     int32 dataBytes;
  647.     
  648.     /* Check for the needed services. */
  649.     
  650.     if (!CheckForServices (globals))
  651.         {
  652.         gResult = 1;
  653.         return;
  654.         }
  655.  
  656.     dataBytes = sizeof (FileHeader) +
  657.                 gStuff->imageRsrcSize +
  658.                 RowBytes (globals) * gStuff->planes * gStuff->imageSize.v;
  659.                       
  660.     if (gStuff->imageMode == plugInModeIndexedColor)
  661.         dataBytes += 3 * sizeof (LookUpTable);
  662.         
  663.     gStuff->minDataBytes = dataBytes;
  664.     gStuff->maxDataBytes = dataBytes;
  665.     
  666.     gStuff->data = NULL;
  667.  
  668.     }
  669.  
  670. /*****************************************************************************/
  671.  
  672. void DoEstimateContinue (GHdl globals)
  673.     {
  674.  
  675.     #pragma unused (globals)
  676.  
  677.     }
  678.  
  679. /*****************************************************************************/
  680.  
  681. void DoEstimateFinish (GHdl globals)
  682.     {
  683.  
  684.     #pragma unused (globals)
  685.  
  686.     }
  687.  
  688. /*****************************************************************************/
  689.  
  690. void DoWritePrepare (GHdl globals)
  691.     {
  692.     
  693.     gStuff->maxData = 0;
  694.     
  695.     }
  696.  
  697. /*****************************************************************************/
  698.  
  699. void DoWriteStart (GHdl globals)
  700.     {
  701.  
  702.     FileHeader header;
  703.     
  704.     if (gResult != noErr)
  705.         return;
  706.         
  707.     /* Check for the needed services. */
  708.     
  709.     if (!CheckForServices (globals))
  710.         {
  711.         gResult = 1;
  712.         return;
  713.         }
  714.  
  715.     /* Write the header. */
  716.     
  717.     gResult = SetFPos (gStuff->dataFork, fsFromStart, 0);
  718.     
  719.     header.mode = gStuff->imageMode;
  720.     header.rows = gStuff->imageSize.v;
  721.     header.cols = gStuff->imageSize.h;
  722.     header.depth = gStuff->depth;
  723.     header.planes = gStuff->planes;
  724.     
  725.     if (gStuff->imageRsrcData)
  726.         header.resourceLength = gStuff->imageRsrcSize;
  727.     else
  728.         header.resourceLength = 0;
  729.         
  730.     WriteSome (globals, sizeof (FileHeader), &header);
  731.     
  732.     if (gResult != noErr)
  733.         return;
  734.     
  735.     /* Write the image resources if any. */
  736.     
  737.     if (header.resourceLength > 0)
  738.         {
  739.         
  740.         WriteSome (globals,
  741.                    header.resourceLength,
  742.                    PILockHandle (gStuff->imageRsrcData, FALSE));
  743.         
  744.         PIUnlockHandle (gStuff->imageRsrcData);
  745.         
  746.         if (gResult != noErr)
  747.             return;
  748.         
  749.         }
  750.         
  751.     /* Write the lookup tables if appropriate. */
  752.     
  753.     if (header.mode == plugInModeIndexedColor)
  754.         {
  755.         
  756.         WriteSome (globals, 3 * sizeof (LookUpTable), &gStuff->redLUT);
  757.         
  758.         if (gResult != noErr)
  759.             return;
  760.         
  761.         }
  762.         
  763.     /* Set up the progress variables. */
  764.     
  765.     gDone = 0;
  766.     gTotal = header.rows * (long) header.planes;
  767.         
  768.     /* Next, we will allocate the pixel buffer. */
  769.     
  770.     AllocatePixelBuffer (globals);
  771.     
  772.     if (gResult != noErr)
  773.         return;
  774.         
  775.     /* Set up to start receiving chunks of data. */
  776.     
  777.     gStuff->theRect.top = 0;
  778.     gStuff->theRect.bottom = 1;
  779.     gStuff->theRect.left = 0;
  780.     gStuff->theRect.right = header.cols;
  781.     gStuff->loPlane = 0;
  782.     gStuff->hiPlane = 0;
  783.     gStuff->colBytes = 1;
  784.     gStuff->rowBytes = gRowBytes;
  785.     gStuff->planeBytes = 0;
  786.     gStuff->data = gPixelData;
  787.     
  788.     }
  789.  
  790. /*****************************************************************************/
  791.  
  792. void DoWriteContinue (GHdl globals)
  793.     {
  794.     
  795.     /* Exit if we have an error. */
  796.     
  797.     if (gResult != noErr)
  798.         {
  799.         gStuff->data = NULL;
  800.         return;
  801.         }
  802.  
  803.     /* Write the row currently in the buffer. */
  804.     
  805.     WriteRow (globals);
  806.     
  807.     if (gResult != noErr)
  808.         {
  809.         gStuff->data = NULL;
  810.         return;
  811.         }
  812.         
  813.     /* Update the progress. */
  814.     
  815.     ++gDone;
  816.     
  817.     UpdateProgress (gDone, gTotal);
  818.     
  819.     /* Advance the rectangle. */
  820.     
  821.     gStuff->theRect.top++;
  822.     gStuff->theRect.bottom++;
  823.     
  824.     /* If we have gone off the end, advance the plane. */
  825.     
  826.     if (gStuff->theRect.top >= gStuff->imageSize.v)
  827.         {
  828.         
  829.         gStuff->theRect.top = 0;
  830.         gStuff->theRect.bottom = 1;
  831.         
  832.         gStuff->loPlane++;
  833.         gStuff->hiPlane++;
  834.         
  835.         /* If we are past the last plane.  Set data to NULL and return. */
  836.         
  837.         if (gStuff->loPlane >= gStuff->planes)
  838.             gStuff->data = NULL;
  839.         
  840.         }
  841.         
  842.     }
  843.  
  844. /*****************************************************************************/
  845.  
  846. void DoWriteFinish (GHdl globals)
  847.     {
  848.     
  849.     DisposePixelBuffer (globals);
  850.     
  851.     gStuff->data = NULL;
  852.         
  853.     }
  854.  
  855.